package com.daleige.httpclient;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.CookieStore;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

public class SynHttpClient {
    private CookieStore cookieStore = new BasicCookieStore();
    private CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
    private RequestConfig requestConfig = null;

    public SynHttpClient() {
        setRequestConfig(5000, 5000, 5000, true);
    }

    /**
     * post表单
     * @param url
     * @param heads 可以为null
     * @param list
     * @return
     * @throws IOException
     */
    public String httpPostFrom(String url, Map<String, String> heads, List<BasicNameValuePair> list) throws IOException {
        UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
        return httpPost(url, heads, entity);
    }

    /**
     * post Json
     * @param url
     * @param heads 可以为null
     * @param params
     * @return
     * @throws IOException
     */
    public String httpPostJson(String url,
                               Map<String, String> heads,
                               String params) throws IOException {
        return httpPostString(url,
                heads,
                params,
                ContentType.create("application/json", "utf-8"));
    }

    /**
     * post String
     * @param url
     * @param heads 可以为null
     * @param params
     * @param contentype
     * @return
     * @throws IOException
     */
    public String httpPostString(String url,
                                 Map<String, String> heads,
                                 String params,
                                 ContentType contentype) throws IOException {
        StringEntity entity = new StringEntity(params, contentype);
        return httpPost(url, heads, entity);
    }

    /**
     * post方法
     * @param url
     * @param heads 可以为null
     * @param entity
     * @return
     * @throws IOException
     */
    public String httpPost(String url, Map<String, String> heads, HttpEntity entity) throws IOException {
        HttpPost httpPost = new HttpPost(url);
        // 设置超时时间
        httpPost.setConfig(requestConfig);
        if (heads != null){
            for (String key:
                    heads.keySet()) {
                httpPost.setHeader(key, heads.get(key));
            }
        }
        // 设置post求情参数
        httpPost.setEntity(entity);
        return getStringResult(httpPost);
    }

    /**
     * get请求
     * @param url
     * @return
     */
    public String httpGet(String url) throws IOException {
        HttpGet httpGet2 = new HttpGet(url);
        httpGet2.setConfig(requestConfig);
        return getStringResult(httpGet2);
    }

    /**
     * 获取返回字符串
     * @param request
     * @return
     * @throws IOException
     */
    private String getStringResult(HttpUriRequest request) throws IOException {
        resetHttpClient(false);
        String strResult = null;
        HttpResponse httpResponse = httpClient.execute(request);
        if (httpResponse != null) {
            if (httpResponse.getStatusLine().getStatusCode() == 200) {
                strResult = EntityUtils.toString(httpResponse.getEntity());
                return strResult;
            }  else {
                strResult = request.getMethod() +
                        "------------" +
                        httpResponse.getStatusLine().toString() +
                        "------------" +
                        EntityUtils.toString(httpResponse.getEntity());
            }
        } else {

        }
        return strResult;
    }

    /**
     * Get下载
     * @param url
     * @return
     * @throws IOException
     */
    public byte[] getDownLoadBytes(String url) throws IOException {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpGet httpget = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpget);
        HttpEntity entity = response.getEntity();
        if (entity == null) {
            return null;
        }
        InputStream in = entity.getContent();
        ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
        byte[] buff = new byte[1024];
        int rc = 0;
        while ((rc = in.read(buff, 0, 1024)) > 0) {
            swapStream.write(buff, 0, rc);
        }
        byte[] in2b = swapStream.toByteArray();
        return in2b;
    }

    /**
     * 请求配置
     * @param connectTimeout 设置连接超时时间
     * @param connectionRequestTimeout 设置请求超时时间
     * @param socketTimeout 设置socket超时时间
     * @param redirectsEnabled 默认允许自动重定向
     */
    public void setRequestConfig(int connectTimeout,
                                 int connectionRequestTimeout,
                                 int socketTimeout,
                                 boolean redirectsEnabled){
        requestConfig = RequestConfig.custom()
                .setConnectTimeout(connectTimeout) // 设置连接超时时间
                .setConnectionRequestTimeout(connectionRequestTimeout) // 设置请求超时时间
                .setSocketTimeout(socketTimeout)
                .setRedirectsEnabled(redirectsEnabled)// 默认允许自动重定向
                .build();
    }

    /**
     * 设置cookie
     * @param cookielist
     */
    public void setCookieStore(List<BasicClientCookie> cookielist ) {
        for(BasicClientCookie cookie:cookielist){
            cookieStore.addCookie(cookie);
        }
    }

    /**
     * 创建cookie
     * @param cookielist
     */
    public void createCookie(List<BasicClientCookie> cookielist ) {
        setCookieStore(cookielist);
    }

    /**
     * 清空cookie
     */
    public void clearCookie(){
        cookieStore.clear();
    }

    /**
     * 重设httpclient
     * @throws IOException
     */
    public void resetHttpClient(boolean reset) throws IOException {
        if(reset || httpClient == null){
            if (httpClient != null){
                httpClient.close();
                httpClient = null;
            }
            httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
        }
    }
}
